/*
 * XMLMenuBar.java
 *
 *  Part of INX: INterfaces in Xml.
 *  Copyright (C) 2007 David Griffiths
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package dg.inx;

import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author davidg
 */

public final class XMLMenuBar extends JMenuBar {
    /**
     * Internationalization strings.
     */
    private ResourceBundle resBundle;

    private Map menus = new HashMap();
    private Map menuItems = new HashMap();
    private Controller controller;
    private Object backingBean;

    public XMLMenuBar(final Object aBean, final String viewXML,
            final ResourceBundle aBundle) {
        super();
        this.backingBean = aBean;
        controller = new Controller(null);
        this.resBundle = aBundle;

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        InputStream in = null;
        try {
            in = XMLMenuBar.class.getResourceAsStream(viewXML);
            Document document = factory.newDocumentBuilder().parse(in);

            Element docMenuBar = (Element) document.getElementsByTagName(
                    "menuBar").item(0);

            //menuBar = new JMenuBar();

            NodeList menuList = docMenuBar.getElementsByTagName("menu");
            for (int i = 0; i < menuList.getLength(); i++) {
                Element menuElement = (Element) menuList.item(i);
                String menuName = menuElement.getTagName();
                String menuTextName = menuElement.getAttribute("textName");
                String menuText = aBundle.getString("menu." + menuTextName);
                JMenu aMenu = new JMenu(menuText);
                menus.put(menuTextName, aMenu);
                add(aMenu);
                NodeList itemList = menuElement.getChildNodes();
                int col = 0;
                for (int j = 0; j < itemList.getLength(); j++) {
                    Node itemNode = (Node) itemList.item(j);
                    if (itemNode instanceof Element) {
                        Element itemElement = (Element) itemNode;
                        String itemName = itemElement.getTagName();
                        String itemTextName = itemElement.getAttribute(
                                "textName");
                        String action = itemElement.getAttribute("action");
                        int keyStroke = 0;
                        String key = itemElement.getAttribute("key");
                        if ((key != null) && (key.length() > 0)) {
                            Class keyEventClass = KeyEvent.class;
                            Field ks = keyEventClass.getDeclaredField(
                                    "VK_" + key);
                            keyStroke = ks.getInt(new Integer(0));
                        }
                        createItem(itemTextName, aMenu, action,
                                new Integer(keyStroke));
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException ioe) {
                }
            }
        }
    }

    public JMenuBar getMenuBar() {
        return this;
    }

    public void createMenus(final JMenuBar menu, final Object[][] params) {
        for (int i = 0; i < params.length; i++) {
            Object[] p = params[i];
            String menuName = (String) p[0];
            createMenu(menuName, menu, (Object[][]) p[1]);
        }
    }

    public void createMenu(final String name, final JMenuBar menu,
            final Object[][] params) {
        String text = resBundle.getString("menu." + name);
        JMenu aMenu = new JMenu(text);
        menus.put(name, aMenu);
        menu.add(aMenu);
        for (int i = 0; i < params.length; i++) {
            Object[] p = params[i];
            if (p.length == 3) {
                createItem((String) p[0], aMenu, (String) p[1], (Integer) p[2]);
            } else if ("-".equals(p[0])) {
                aMenu.addSeparator();
            } else {
                createItem((String) p[0], aMenu, (String) p[1]);
            }
        }
    }

    public void createItem(final String name, final JMenu menu,
            final String action) {
        createItem(name, menu, action, new Integer(0));
    }

    public void createItem(final String name, final JMenu menu,
            final String action, final Integer keyStroke) {
        KeyStroke ks = null;
        if (keyStroke.intValue() != 0) {
            ks = KeyStroke.getKeyStroke(keyStroke.intValue(),
                    Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
        }
        createItem(name, menu, action, ks);
    }

    public void createItem(final String name, final JMenu menu,
            final String action, final KeyStroke keyStroke) {
        String text = "-";
        if (!"-".equals(name)) {
            text = resBundle.getString("menu." + name);
        } else {
            menu.addSeparator();
            return;
        }
        JMenuItem item = new JMenuItem(text);
        menu.add(item);
        if (keyStroke != null) {
            item.setAccelerator(keyStroke);
        }
        menuItems.put(name, item);
        controller.bindMethod(backingBean, action, item);
    }

    public JMenu getMenu(final String name) {
        return (JMenu) menus.get(name);
    }

    public JMenuItem getItem(final String name) {
        return (JMenuItem) menuItems.get(name);
    }
}